import { IconClose, IconSave } from '@arco-design/web-react/icon';
import DetailCard from '@src/components/detailCard';
import DetailItem from '@src/components/detailItem';
import LoadingMask from '@src/components/loadingMask';
import { MenuTypes } from '@src/components/mainNavBar';
import { Menu } from '@src/page/system/menu/types';
import { createStoreDetailKey, detailRequest, detailUpdate } from '@src/redux/detailReducer';
import { createStoreListKey, listRequest } from '@src/redux/listReducer';
import { AppStore, Record, RecordList, ValidateRule } from '@src/types';
import { cloneDeep, validateField } from '@src/utils/utils';
import {
  Button,
  Checkbox,
  Grid,
  Input,
  Radio,
  Select,
  Tabs,
  TreeSelect,
  Message,
  Typography,
} from '@arco-design/web-react';
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate, useParams } from 'react-router-dom';
import { DictType, GenDetail } from './types';
const { Row, Col } = Grid;
interface Props {
  currentRouteRecord: MenuTypes;
}
// 生成类型
const genType = [
  { label: 'zip压缩包', value: '0' },
  { label: '自定义路径', value: '1' },
];

// 生成模板
const tplCategory = [
  { label: '单表（增删改查）', value: 'crud' },
  { label: '树表（增删改查）', value: 'tree' },
  { label: '主子表（增删改查）', value: 'sub' },
];

// java类型字典
const javaType = [
  { label: 'Long', value: 'Long' },
  { label: 'String', value: 'String' },
  { label: 'Integer', value: 'Integer' },
  { label: 'Double', value: 'Double' },
  { label: 'BigDecimal', value: 'BigDecimal' },
  { label: 'Date', value: 'Date' },
  { label: 'Boolean', value: 'Boolean' },
];
// 查询类型
const queryTtyp = [
  { label: '=', value: 'EQ' },
  { label: '!=', value: 'NE' },
  { label: '>', value: 'GT' },
  { label: '>=', value: 'GE' },
  { label: '<', value: 'LT' },
  { label: '<=', value: 'LE' },
  { label: 'LIKE', value: 'LIKE' },
  { label: 'BETWEEN', value: 'BETWEEN' },
];
// 显示类型
const htmlType = [
  { label: '文本框', value: 'input' },
  { label: '文本域', value: 'textarea' },
  { label: '下拉框', value: 'select' },
  { label: '单选框', value: 'radio' },
  { label: '复选框', value: 'checkbox' },
  { label: '日期控件', value: 'datetime' },
  { label: '图片上传', value: 'imageUpload' },
  { label: '文件上传', value: 'fileUpload' },
  { label: '富文本控件', value: 'editor' },
];

const model = 'code';
const table = 'gen';
// 字段验证规则
const rule: ValidateRule = {
  tableName: { required: true, message: '表名称不能为空' },
  tableComment: { required: true, message: '表描述不能为空' },
  className: { required: true, message: '实体类名不能为空' },
  functionAuthor: { required: true, message: '作者不能为空' },
  tplCategory: { required: true, message: '生成模板不能为空' },
  packageName: { required: true, message: '生成包路径不能为空' },
  moduleName: { required: true, message: '生成模块名不能为空' },
  businessName: { required: true, message: '生成业务名不能为空' },
  functionName: { required: true, message: '生成功能名不能为空' },
};

export default function CardSupplierDetailPage({ currentRouteRecord }: Props) {
  // 详情id 不论代表id的字段是什么，跳转的时候都用id
  const { id } = useParams();
  const dispatch = useDispatch();
  const navigate = useNavigate();
  // 每次编辑时修改的数据
  const [detailData, setDetailData] = useState<GenDetail | null | undefined>({
    info: { tplCategory: 'crud' },
    rows: [],
    tables: [],
  });
  // 数据验证结果
  const [errorData, setErrorData] = useState<{ [x: string]: any }>({});

  // --------------额外数据--------------------------------------
  // -----------------------------------------------------------

  // 当前详情 根据id的值区分页面模式
  const detail: Record<GenDetail> = useSelector(
    (state: AppStore) => state.detail?.[createStoreDetailKey({ model, table, id: id! })]
  );
  // 字典名列表
  const dictOptionList: RecordList<DictType> = useSelector(
    (state: AppStore) => state.list?.[createStoreListKey({ model: 'system', table: 'dict', path: 'type/optionselect' })]
  );
  const menuList: RecordList<Menu> = useSelector(
    (state: AppStore) => state.list?.[createStoreListKey({ model: 'system', table: 'menu' })]
  );

  // 页面初次渲染时获取数据
  useEffect(() => {
    if (id && id !== 'create') {
      handleRefreshData();
    }
    dispatch(listRequest({ model: 'system', table: 'dict', path: 'type/optionselect' }));
    dispatch(listRequest({ model: 'system', table: 'menu' }));
  }, []); //eslint-disable-line

  // 页面详情数据获取到后存入编辑数据
  useEffect(() => {
    if (id !== 'create' && detail?.loaded && detail?.result) {
      let result = detail?.result;
      setDetailData(result);
      // 需要依赖详情数据加载别的数据的 在这里写
    }
  }, [detail]); //eslint-disable-line

  // 当前详情数据请求
  function handleRefreshData(forceRefresh?: boolean, callback?: (code?: number, msg?: string) => void) {
    if (id && id !== 'create') {
      dispatch(detailRequest({ model, table, id, forceRefresh, callback }));
    }
  }

  // 任意字段修改时存入编辑数据
  function handleChangeInfo(key: string, value: any, secondKey?: string, secondValue?: any) {
    setErrorData({});
    let data: any = cloneDeep(detailData);
    data.info[key] = value;
    if (secondKey) {
      data.info[secondKey] = secondValue;
    }
    setDetailData(data);
  }

  function handleChangeRows(id: string, key: string, value: any) {
    setErrorData({});
    let data: any = cloneDeep(detailData);
    for (let i in data.rows) {
      if (data.rows[i].columnId === id) {
        data.rows[i][key] = value;
        break;
      }
    }
    setDetailData(data);
  }

  // 保存基本信息
  async function handleSave() {
    let validateRes = validateField(detailData?.info, rule);
    setErrorData(validateRes);
    if (Object.keys(validateRes).length) return;

    LoadingMask.show('正在保存...');
    dispatch(
      detailUpdate({
        model,
        table,
        id: id!,
        detail: Object.assign({}, detailData?.info, {
          columns: detailData?.rows,
          params: {
            treeCode: detailData?.info?.treeCode,
            treeName: detailData?.info?.treeName,
            treeParentCode: detailData?.info?.treeParentCode,
            parentMenuId: detailData?.info?.parentMenuId,
          },
        }),
        callback(code, msg, record) {
          let _msg = code === 200 ? Message.success : Message.warning;
          if (id === 'create') {
            navigate(-1);
          }
          LoadingMask.hide();
          _msg(msg ?? '');
        },
      })
    );
  }

  //----------------额外操作 / 数据-------------------

  //-------------------------------------------------
  // 上级菜单树
  let parentList: Menu[] = menuList?.results || [];
  parentList = parentList.filter((i) => i.menuType !== 'F');
  type TreeSelectDataType = {
    title: string;
    key: string;
    parentId?: number | string;
    children?: TreeSelectDataType[];
  };
  let map: { [x: string]: TreeSelectDataType } = {};
  parentList.forEach((i) => {
    map[i.menuId?.toString() ?? ''] = {
      title: i.menuName!,
      key: i.menuId!.toString(),
      parentId: i.parentId,
      children: [],
    };
  });
  Object.keys(map).forEach((i) => {
    let data = map[i];
    if (data.parentId && map[data.parentId?.toString() ?? '']) {
      map[data.parentId?.toString() ?? ''].children!.push(data);
    }
  });

  let treeList: TreeSelectDataType[] = [];

  Object.keys(map).forEach((i) => {
    let data = map[i];
    if (!data.parentId) {
      treeList.push(data);
    } else if ((data.children?.length ?? 0) <= 0) {
      delete data.children;
    }
  });
  treeList = [{ title: '根目录', key: '0', children: treeList }];

  let tabItems = [
    {
      key: '1',
      label: '基本信息',
      children: (
        <div>
          <DetailCard showTitle={false} className="bpl-30 bpr-30">
            <DetailItem label="表名称" required labelSpan={4} outlet={4} error={errorData.tableName}>
              <Input
                className="m-input"
                value={detailData?.info?.tableName}
                onChange={(v) => handleChangeInfo('tableName', v)}
              />
            </DetailItem>
            <DetailItem label="表描述" required labelSpan={4} outlet={4} error={errorData.tableComment}>
              <Input
                className="m-input"
                value={detailData?.info?.tableComment}
                onChange={(v) => handleChangeInfo('tableComment', v)}
              />
            </DetailItem>
            <DetailItem label="实体类名" required labelSpan={4} outlet={4} error={errorData.className}>
              <Input
                className="m-input"
                value={detailData?.info?.className}
                onChange={(v) => handleChangeInfo('className', v)}
              />
            </DetailItem>
            <DetailItem label="作者" required labelSpan={4} outlet={4} error={errorData.functionAuthor}>
              <Input
                className="m-input"
                value={detailData?.info?.functionAuthor}
                onChange={(v) => handleChangeInfo('functionAuthor', v)}
              />
            </DetailItem>

            <DetailItem label="备注" labelSpan={4} outlet={4} error={errorData.remark}>
              <Input.TextArea
                className="m-input-area"
                autoSize={{ minRows: 4 }}
                value={detailData?.info?.remark}
                onChange={(v) => handleChangeInfo('remark', v)}
              />
            </DetailItem>
          </DetailCard>
        </div>
      ),
    },
    {
      key: '2',
      label: '字段信息',
      children: (
        <div className="text-second-color">
          <Row className="pt-10 pb-10 bg-page">
            <Col span={2}>序号</Col>
            <Col span={2}>字段列名</Col>
            <Col span={2}>字段描述</Col>
            <Col span={2}>物理类型</Col>
            <Col span={2}>java类型</Col>
            <Col span={2}>java属性</Col>
            <Col span={1}>新增</Col>
            <Col span={1}>编辑</Col>
            <Col span={1}>列表</Col>
            <Col span={1}>查询</Col>
            <Col span={2}>查询方式</Col>
            <Col span={1}>必填</Col>
            <Col span={2}>显示类型</Col>
            <Col span={3}>字典类型</Col>
          </Row>
          {(detailData?.rows ?? []).map((i) => (
            <Row className="pt-10 pb-10 ai-center">
              <Col span={2} className="pr-20">
                {i.columnId}
              </Col>
              <Col span={2} className="pr-20">
                {i.columnName}
              </Col>
              <Col span={2} className="pr-20">
                <Input
                  className="m-input"
                  value={i.columnComment}
                  onChange={(v) => handleChangeRows(i.columnId!, 'columnComment', v)}
                />
              </Col>
              <Col span={2} className="pr-20">
                {i.columnType}
              </Col>
              <Col span={2} className="pr-20">
                <Select
                  className="m-select"
                  value={i.javaType}
                  options={javaType}
                  onChange={(v) => handleChangeRows(i.columnId!, 'javaType', v)}
                />
              </Col>
              <Col span={2} className="pr-20">
                <Input
                  className="m-input"
                  value={i.javaField}
                  onChange={(v) => handleChangeRows(i.columnId!, 'javaField', v)}
                />
              </Col>
              <Col span={1} className="pr-20">
                <Checkbox
                  checked={i.isInsert === '1'}
                  onChange={(v) => handleChangeRows(i.columnId!, 'isInsert', v ? '1' : '0')}
                />
              </Col>
              <Col span={1} className="pr-20">
                <Checkbox
                  checked={i.isEdit === '1'}
                  onChange={(v) => handleChangeRows(i.columnId!, 'isEdit', v ? '1' : '0')}
                />
              </Col>
              <Col span={1} className="pr-20">
                <Checkbox
                  checked={i.isList === '1'}
                  onChange={(v) => handleChangeRows(i.columnId!, 'isList', v ? '1' : '0')}
                />
              </Col>
              <Col span={1} className="pr-20">
                <Checkbox
                  checked={i.isQuery === '1'}
                  onChange={(v) => handleChangeRows(i.columnId!, 'isQuery', v ? '1' : '0')}
                />
              </Col>
              <Col span={2} className="pr-20">
                <Select
                  className="bw-100"
                  value={i.queryType}
                  options={queryTtyp}
                  onChange={(v) => handleChangeRows(i.columnId!, 'queryType', v)}
                />
              </Col>
              <Col span={1} className="pr-20">
                <Checkbox
                  checked={i.isRequired === '1'}
                  onChange={(v) => handleChangeRows(i.columnId!, 'isRequired', v ? '1' : '0')}
                />
              </Col>
              <Col span={2} className="pr-20">
                <Select
                  className="m-select"
                  value={i.htmlType}
                  options={htmlType}
                  onChange={(v) => handleChangeRows(i.columnId!, 'htmlType', v)}
                />
              </Col>
              <Col span={3} className="pr-20">
                <Select
                  className="m-select"
                  value={i.dictType}
                  onChange={(v) => handleChangeRows(i.columnId!, 'dictType', v)}
                  options={(dictOptionList?.results ?? []).map((i) => ({
                    label: (
                      <div className="d-flex-r">
                        <div>{i.dictName}</div>
                        <div className="flex-1 text-right">{i.dictType}</div>
                      </div>
                    ),
                    value: i.dictType!,
                  }))}
                />
              </Col>
            </Row>
          ))}
        </div>
      ),
    },
    {
      key: '3',
      label: '生成信息',
      children: (
        <div>
          <DetailCard showTitle={false} className="bpl-20 bpr-20">
            <DetailItem label="生成模板" required labelSpan={8} outlet={2}>
              <Select
                className="m-select"
                value={detailData?.info?.tplCategory}
                options={tplCategory}
                onChange={(v) => handleChangeInfo('tplCategory', v)}
              />
            </DetailItem>
            <DetailItem label="生成包路径" required labelSpan={8} outlet={2}>
              <Input
                className="m-input"
                value={detailData?.info?.packageName}
                onChange={(v) => handleChangeInfo('packageName', v)}
              />
            </DetailItem>
            <DetailItem label="生成模块名" required labelSpan={8} outlet={2}>
              <Input
                className="m-input"
                value={detailData?.info?.moduleName}
                onChange={(v) => handleChangeInfo('moduleName', v)}
              />
            </DetailItem>
            <DetailItem label="生成业务名" required labelSpan={8} outlet={2}>
              <Input
                className="m-input"
                value={detailData?.info?.businessName}
                onChange={(v) => handleChangeInfo('businessName', v)}
              />
            </DetailItem>
            <DetailItem label="生成功能名" required labelSpan={8} outlet={2}>
              <Input
                className="m-input"
                value={detailData?.info?.functionName}
                onChange={(v) => handleChangeInfo('functionName', v)}
              />
            </DetailItem>
            <DetailItem label="上级菜单" labelSpan={8} outlet={2} error={errorData.parentId}>
              <TreeSelect
                className="m-tree-select"
                value={detailData?.info?.parentMenuId?.toString()}
                treeData={treeList}
                onChange={(v, exa) => {
                  handleChangeInfo('parentMenuId', v, 'parentMenuName', exa.trigger?.title);
                }}
              />
            </DetailItem>
            <DetailItem label="代码生成方式" labelSpan={4} outlet={4}>
              <Radio.Group
                value={detailData?.info?.genType}
                options={genType}
                onChange={(v) => handleChangeInfo('genType', v.target.value)}
              />
            </DetailItem>
            {detailData?.info?.genType === '1' && (
              <DetailItem label="代码生成路径" labelSpan={4} outlet={4}>
                <Input
                  className="m-input"
                  value={detailData?.info?.genPath}
                  onChange={(v) => handleChangeInfo('genPath', v)}
                />
              </DetailItem>
            )}
          </DetailCard>
          {detailData?.info?.tplCategory === 'tree' && (
            <DetailCard title="其他信息" className="bpl-20 bpr-20">
              <DetailItem label="树编码字段" labelSpan={8} outlet={2}>
                <Select
                  className="m-select"
                  value={detailData?.info?.treeCode}
                  options={(detailData?.info?.columns ?? []).map((i) => ({
                    label: i.columnName + ' : ' + i.columnComment,
                    value: i.columnName!,
                  }))}
                  onChange={(v) => handleChangeInfo('treeCode', v)}
                />
              </DetailItem>
              <DetailItem label="父树编码字段" labelSpan={8} outlet={2}>
                <Select
                  className="m-select"
                  value={detailData?.info?.treeParentCode}
                  options={(detailData?.info?.columns ?? []).map((i) => ({
                    label: i.columnName + ' : ' + i.columnComment,
                    value: i.columnName!,
                  }))}
                  onChange={(v) => handleChangeInfo('treeParentCode', v)}
                />
              </DetailItem>
              <DetailItem label="树名称字段" labelSpan={8} outlet={2}>
                <Select
                  className="m-select"
                  value={detailData?.info?.treeName}
                  options={(detailData?.info?.columns ?? []).map((i) => ({
                    label: i.columnName + ' : ' + i.columnComment,
                    value: i.columnName!,
                  }))}
                  onChange={(v) => handleChangeInfo('treeName', v)}
                />
              </DetailItem>
            </DetailCard>
          )}
          {detailData?.info?.tplCategory === 'sub' && (
            <DetailCard title="其他信息" className="bpl-20 bpr-20">
              <DetailItem label="关联子表的表名" labelSpan={8} outlet={2}>
                <Select
                  className="m-select"
                  value={detailData?.info?.subTableName}
                  options={(detailData?.tables ?? []).map((i) => ({
                    label: i.tableName + ' : ' + i.tableComment,
                    value: i.tableName!,
                  }))}
                  onChange={(v) => handleChangeInfo('subTableName', v)}
                />
              </DetailItem>
              <DetailItem label="子表关联的外键名" labelSpan={8} outlet={2}>
                <Select
                  className="m-select"
                  value={detailData?.info?.subTableFkName}
                  options={(
                    (detailData?.tables ?? []).find((j) => j.tableName === detailData?.info?.subTableName)?.columns ??
                    []
                  ).map((i) => ({
                    label: i.columnName + ' : ' + i.columnComment,
                    value: i.columnName!,
                  }))}
                  onChange={(v) => handleChangeInfo('subTableFkName', v)}
                />
              </DetailItem>
            </DetailCard>
          )}
        </div>
      ),
    },
  ];

  return (
    <div className="page detail-page p-20 bg-white">
      <div className="scroll-bar-h-min">
        <Tabs defaultActiveTab="1">
          {tabItems.map((i) => (
            <Tabs.TabPane key={i.key} title={i.label}>
              <Typography.Paragraph>{i.children}</Typography.Paragraph>
            </Tabs.TabPane>
          ))}
        </Tabs>
      </div>
      <div className="d-flex-r ai-center jc-center bw-100 p-20">
        <Button icon={<IconClose />} className="mr-20" type="outline" onClick={() => navigate(-1)}>
          关闭
        </Button>
        <Button icon={<IconSave />} type="primary" onClick={handleSave}>
          提交
        </Button>
      </div>
    </div>
  );
}
